package service

import (
	"asuOfficialApi/comm"
	"asuOfficialApi/dao"
	"asuOfficialApi/db"
	"asuOfficialApi/model"
	"fmt"
)

type UserService interface {
	FindById(id int64) (user *model.User, err *comm.Err)
	Register(username, password string) (user *model.User, err *comm.Err)
	Login(username, password string) (user *model.User, err *comm.Err)
}

type userService struct {
	dao *dao.UserDao
}

func NewUserService() UserService {
	return &userService{
		dao: dao.NewUserDao(db.DB),
	}
}

func (s *userService) FindById(id int64) (user *model.User, err *comm.Err) {
	data := s.getByCache(id)
	if data == nil {
		if data = s.dao.FindById(id); data != nil {
			s.setByCache(data)
		} else {
			data = nil
		}
	}
	if data == nil {
		return nil, comm.NewError(comm.ErrorNotExist, "用户不存在")
	} else {
		return data, nil
	}
}

func (s *userService) Register(username, password string) (user *model.User, err *comm.Err) {
	if exist := s.dao.CheckExist(username); exist {
		return nil, comm.NewError(comm.ErrorExist, "用户已存在")
	}

	user = s.dao.InsertUser(username, password)
	return user, nil
}

func (s *userService) Login(username, password string) (user *model.User, err *comm.Err) {
	if exist := s.dao.CheckExist(username); !exist {
		return nil, comm.NewError(comm.ErrorNotExist, "用户不存在")
	}

	if user = s.dao.CheckAccount(username, password); user != nil {
		return user, nil
	} else {
		return nil, comm.NewError(comm.ErrorNotExist, "用户名或者密码错误")
	}
}

// 从缓存中得到信息
func (s *userService) getByCache(id int64) *model.User {
	key := fmt.Sprintf("info_user_%d", id)
	dataMap := db.HGetByCache(key).(map[string]string)
	dataId := comm.GetInt64FromStringMap(dataMap, "Id", 0)
	if dataId <= 0 {
		return nil
	}
	var data = &model.User{
		Id:       dataId,
		Username: comm.GetStringFromStringMap(dataMap, "Username", ""),
	}
	return data
}

// 将信息更新到缓存
func (s *userService) setByCache(data *model.User) {
	if data == nil || data.Id <= 0 {
		return
	}
	id := data.Id
	key := fmt.Sprintf("info_user_%d", id)
	// 数据更新到redis缓存
	params := []interface{}{key}
	params = append(params, "Id", id)
	if data.Username != "" {
		params = append(params, "Username", data.Username)
		params = append(params, "CreateAt", data.CreateAt)
		params = append(params, "UpdateAt", data.UpdateAt)
	}
	db.HSetByCache(key, params)
}

// 直接清空缓存数据
func (s *userService) delByCache(data *model.User, columns []string) {
	if data == nil || data.Id <= 0 {
		return
	}
	key := fmt.Sprintf("info_user_%d", data.Id)
	db.DelByCache(key)
}
